package com.zssj.common.utils;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.jsonwebtoken.Claims;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import com.zssj.common.spring.ApplicationUtils;
import com.zssj.common.cons.APICons;
import com.zssj.framework.enums.ErrorCodeEnum;
import com.zssj.framework.utils.ApiAssert;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * API工具类
 *
 * @author Caratacus
 */
@SuppressWarnings("ALL")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public abstract class ApiUtils {


    private static final ThreadLocal<Object> THREAD_DEPT_IDS = new ThreadLocal<>();

    /**
     * 获取当前用户id
     */
    public static Long currentUid() {
        Long uid = (Long) ApplicationUtils.getRequest().getAttribute(APICons.API_UID);
        if (Objects.isNull(uid)) {
            String token = ApplicationUtils.getRequest().getHeader("Authorization");
            ApiAssert.notNull(ErrorCodeEnum.UNAUTHORIZED, token);
            token = token.replaceFirst("Bearer ", "");
            Claims claims = JWTUtils.getClaim(token);
            ApiAssert.notNull(ErrorCodeEnum.UNAUTHORIZED, claims);
            return claims.get(JWTUtils.UID, Long.class);
        }
        return uid;
    }
    /**
     * 获取部门id
     */
    public static Long currentDeptId(){
        Long deptId = (Long) ApplicationUtils.getRequest().getAttribute(APICons.API_DEPT_ID);
        if (Objects.isNull(deptId)) {
            String token = ApplicationUtils.getRequest().getHeader("Authorization");
            ApiAssert.notNull(ErrorCodeEnum.UNAUTHORIZED, token);
            token = token.replaceFirst("Bearer ", "");
            Claims claims = JWTUtils.getClaim(token);
            ApiAssert.notNull(ErrorCodeEnum.UNAUTHORIZED, claims);
            return claims.get("deptId", Long.class);
        }
        return deptId;
    }
    //网页抓取内容
    public static void getxs() {
        try {
            Map<String, String> cookies = new HashMap<>();
            cookies.put("Hm_lvt_2dad18f469b51c06346e4b447e60789d","1594710488");
            Connection con = Jsoup.connect("http://nongcunbs.sdflc.com/#!taskUser");
            // 配置模拟浏览器
            con.header("Accept", "*/*");
            con.header("Accept-Encoding", "gzip, deflate");
            con.header("Accept-Language", "zh-CN,zh;q=0.9");
            con.header("Referer", "https://www.wshulou.com/");
            con.header("Host", "www.txt8.net");
            con.header("Connection", "keep-alive");
            con.header("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36");
            con.header("Upgrade-Insecure-Requests", "1");
            con.cookies(cookies);
//            con.ignoreContentType(true);
            con.method(Connection.Method.GET);
            Connection.Response getData = con.execute();// 获取响应
            Thread.sleep(10000);
            System.out.println(getData.body());

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

//
//    public static void setDeptIds(List<Long> deptIds) {
//        THREAD_DEPT_IDS.set(deptIds);
//    }
//
//    public static List<Long> getDeptIds() {
//        return (List<Long>) THREAD_DEPT_IDS.get();
//    }
    private static String NUMBER_CHARS = "0123456789";
    private static String LETTER_CHARS = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789";

    /**
     * 产生指定位数的随机字符串(包含字母)
     *
     * @param length 长度
     * @return 随机数
     */
    public static String generateRandomChars(int length) {
        char[] charsArray = NUMBER_CHARS.toCharArray();
        Random random = new Random(System.currentTimeMillis());
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(charsArray[random.nextInt(charsArray.length)]);
        }
        return sb.toString();
    }

    /**
     * 获取ip地址
     * @param request
     * @return
     */
    public static String getIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String[] ips = ip.split(",");
        return "0:0:0:0:0:0:0:1".equals(ips[0])?"127.0.0.1":ips[0];
    }

    /**
     * 根据ip获取详细地址
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) {
        try {
            String path = "ip2region/ip2region.db";
//            String path = ApiUtils.class.getResource("/ip2region/ip2region.db").getPath();
            String name = "ip2region.db";
            int algorithm = DbSearcher.BTREE_ALGORITHM;
            DbConfig config = new DbConfig();
            System.out.println("==="+new ClassPathResource(path).getStream());
            File file = FileUtil.inputStreamToFile(new ClassPathResource(path).getStream(), name);
            DbSearcher searcher = new DbSearcher(config, file.getPath());
            Method method = null;
//            switch (algorithm) {
//                case DbSearcher.BTREE_ALGORITHM:
//                    method = searcher.getClass().getMethod("btreeSearch", String.class);
//                    break;
//                case DbSearcher.BINARY_ALGORITHM:
//                    method = searcher.getClass().getMethod("binarySearch", String.class);
//                    break;
//                case DbSearcher.MEMORY_ALGORITYM:
//                    method = searcher.getClass().getMethod("memorySearch", String.class);
//                    break;
//                default:
//                    method = searcher.getClass().getMethod("memorySearch", String.class);
//                    break;
//            }
            method = searcher.getClass().getMethod("btreeSearch", String.class);
            DataBlock dataBlock = null;
            if ( Util.isIpAddress(ip) == false ) {
                System.out.println("Error: Invalid ip address");
            }
            dataBlock = (DataBlock) method.invoke(searcher, ip);
            String address = dataBlock.getRegion().replace("0|","");
            if(address.charAt(address.length()-1) == '|'){
                address = address.substring(0,address.length() - 1);
            }
            return address.equals(ElAdminConstant.REGION)?"内网IP":address;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    //构建树
    public static <T> JSONArray buildTree(List<T>  list, Long parentId){
        JSONArray resultList = new JSONArray();
        for (T t : list) {
            JSONObject obj = JSONUtil.parseObj(t);
            Long id = new Long(obj.get("id").toString());
            Long pId = new Long(obj.get("parentId").toString());
            if (parentId.intValue() == pId.intValue()) {
                JSONArray children = buildTree(list, id);
                if(children!=null && children.size() >0){
                    obj.put("children",children);
                }
                resultList.add(obj);
            }
        }
        return resultList;
    }

    public static List<Long> getDeptIdList(String path){
        String[] arr = path.split("\\|");
        Long[] parentIds = (Long[]) ConvertUtils.convert(arr,Long.class);
        List<Long> list= Arrays.asList(parentIds);
        List<Long> deptIdList = new ArrayList<Long>(list);
        deptIdList.remove(0);
        return deptIdList;
    }
    public static boolean isLetter(char c) {
        int k = 0x80;
        return c / k == 0 ? true : false;
    }


    /**
     * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
     * @param String s 需要得到长度的字符串
     * @return int 得到的字符串长度
     */
    public static int length(String s) {
        if (s == null)
            return 0;
        char[] c = s.toCharArray();
        int len = 0;
        for (int i = 0; i < c.length; i++) {
            len++;
            if (!isLetter(c[i])) {
                len++;
            }
        }
        return len;
    }

    public static long fromDateStringToLong(String inVal) {
        Date date = null;
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
        try {
            date = inputFormat.parse(inVal);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date.getTime();
    }


}
